﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web.Mvc;
using InnovaApp.Layers.CommonLayer;
using InnovaApp.Layers.DataLayer;
using InnovaApp.Layers.DomainLayer;
using InnovaApp.Layers.ResourcesLayer.Properties;
using InnovaApp.Portals.MVC4Portal.Models;
using InnovaApp.Portals.MVC4Portal.Models.JSonModels;
using InnovaApp.Portals.MVC4Portal.Models.MetaModels;
using InnovaApp.Portals.MVC4Portal.Models.MetaModels.OrderManagement;
using INNOVACALL.Framework.Common;
using INNOVACALL.Framework.Common.CodeFormatting;
using INNOVACALL.Framework.Common.Models;
using INNOVACALL.Framework.Common.MVCHelpers;

namespace InnovaApp.Portals.MVC4Portal.Controllers
{
    /// <summary>
    /// Controller inherits _Controllers_Base<T> to avoid use of untyped ViewBag
    /// Copy Home controller and Replace Home by AdvancedSamples_OrderWithDetails
    /// </summary>
    public class AdvancedSamples_OrderWithDetailsController : _Controllers_Base<AdvancedSamples_OrderWithDetailsModel>
    {
        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            base.eMethodBase = "InnovaApp.Portals.InnovaAppFrontOfficePortal.Controllers.AdvancedSamples_OrderWithDetailsController";
            base.specificCssCollection = new string[] { "_FormCommon.css", "Views/AdvancedSamples_OrderWithDetails.css", "ClientComponents/CodeFormatting/csharp.css", "ClientComponents/KendoUI/kendo.common.min.css", "ClientComponents/KendoUI/kendo.blueopal.min.css" };
            base.specificJSCollection = null;
            base.dynamicJSCollection = new string[] { "/ScriptsG/inoAdvancedSamples_OrderWithDetailsDynamic.js" };
            base.specificJqueryJSCollection = new string[] { "ClientComponents/KendoUI/kendo.web.min.js", "InnovacallJS/views.js", "InnovacallJS/AdvancedSamples_OrderWithDetails/AdvancedSamples_OrderWithDetails.js" };
            base.jsVariables = null;
            base.externalCSS = null;
            base.Meta.Add(enMeta.Description, Resources.View_AdvancedSamples_OrderWithDetails_Meta_Description);
            base.Meta.Add(enMeta.Keywords, Resources.View_AdvancedSamples_OrderWithDetails_Meta_Keywords);
            base.Meta.Add(enMeta.Subject, Resources.View_AdvancedSamples_OrderWithDetails_Meta_Subject);

            base.Initialize(requestContext);
        }

        /// <summary>
        /// Initial response
        /// </summary>
        /// <returns></returns>
        [HttpGet, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
        public ActionResult Index()
        {
            //NEVER USES VIEW BAG AGAIN !
            //ViewBag.Message = "Modify this template to kick-start your ASP.NET MVC application.";
            using (DataRepositories _dataContext = new DataRepositories())
            {
                base.InitView(
                    Resources.View_AdvancedSamples_OrderWithDetails_PageTitle,
                    string.Empty,
                    specificCssCollection,
                    specificJSCollection,
                    dynamicJSCollection,
                    specificJqueryJSCollection,
                    jsVariables,
                    externalCSS,
                    Meta,
                    _dataContext,
                    true);
                try
                {

                    PrepareEmptyOrder(_dataContext);
                    string OpenMessage = string.Empty;
                    //Opening behavior
                    if (ContentData.CurrentOrder.DeliveryAddresses.Count == 1 && ContentData.CurrentOrder.InvoicingAddresses.Count == 1)
                    {
                        OpenMessage = Resources.View_AdvancedSamples_OrderWithDetails_ErrMsg_CustomerDeliveryAndInvoiceAddressMustBeSetBefore;
                    }
                    else if (ContentData.CurrentOrder.DeliveryAddresses.Count == 1)
                    {
                        OpenMessage = Resources.View_AdvancedSamples_OrderWithDetails_ErrMsg_CustomerDeliveryAddressMustBeSetBefore;
                    }
                    else if (ContentData.CurrentOrder.InvoicingAddresses.Count == 1)
                    {
                        OpenMessage = Resources.View_AdvancedSamples_OrderWithDetails_ErrMsg_CustomerInvoiceAddressMustBeSetBefore;
                    }
                    if (OpenMessage != string.Empty)
                    {
                        string returnURL = Server.UrlEncode(Request.Url.AbsoluteUri);
                        string ScriptToExecute = string.Format("$.fn.jqDialogAlert('{0}','{1}','{2}{3}');",
                            Resources.View_AdvancedSamples_OrderWithDetails_ErrMsg_Customer_AddressMissing_Title,
                            OpenMessage,
                            "/AdvancedSamples_AddressesManagement?ReturnUrl=",
                            returnURL);
                        base.jsVariables = new string[] { "var scriptToExecute='" + ScriptToExecute.Replace("\'", "\\\'") + "'" };
                        ContentData._JSVariables = base.jsVariables.ToList();
                    }
                }
                catch (INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException iDIe)
                {
                    string returnURL = Server.UrlEncode(Request.Url.AbsoluteUri);
                    string ScriptToExecute = string.Format("$.fn.jqDialogAlert('{0}','{1}','{2}{3}');",
                        Resources.View_AdvancedSamples_ErrMsgContactAccountNotCreated_Title,
                        Resources.View_AdvancedSamples_ErrMsgContactAccountNotCreated_Message,
                        "/Sample_BasicForm_MyProfile?ReturnUrl=",
                        returnURL);
                    base.jsVariables = new string[] { "var scriptToExecute='" + ScriptToExecute.Replace("\'", "\\\'") + "'" };
                    ContentData.CurrentOrder = new Order_MetaModel();
                    ContentData._JSVariables = base.jsVariables.ToList();
                }

                #region Involved code rendering
                INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel InvolvedSourceCode;
                INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel InvolvedSubSourceCode;
                ContentData.InvolvedCode = new InvolvedCodeModel();
                InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();

                #region Views, partials & template editors

                InvolvedSourceCode.TabStripName = "Views, partials & template editors";
                InvolvedSourceCode.TabStripContent = string.Empty;
                InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;

                InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "View", TabStripContent = "/Views/AdvancedSamples_OrderWithDetails/Index.cshtml" };
                InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

                InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "Layout", TabStripContent = "/Views/Shared/_Layout.cshtml" };
                InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

                InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
                InvolvedSubSourceCode.TabStripName = "Partials";
                InvolvedSubSourceCode.TabStripContent = string.Empty;
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "_AdvancedSamples_OrderWithDetails_DetailRefresh.cshtml", TabStripContent = "/Views/Shared/_AdvancedSamples_OrderWithDetails_DetailRefresh.cshtml" });
                InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

                InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
                InvolvedSubSourceCode.TabStripName = "Editor templates";
                InvolvedSubSourceCode.TabStripContent = string.Empty;
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "Order_MetaModel.cshtml", TabStripContent = "/Views/Shared/EditorTemplates/Order_MetaModel.cshtml" });
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "OrderDetail_MetaModel.cshtml", TabStripContent = "/Views/Shared/EditorTemplates/OrderDetail_MetaModel.cshtml" });
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "OrderTotal_MetaModel.cshtml", TabStripContent = "/Views/Shared/EditorTemplates/OrderTotal_MetaModel.cshtml" });
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "Order_MetaModel_Refresh.cshtml", TabStripContent = "/Views/Shared/EditorTemplates/Order_MetaModel_Refresh.cshtml" });
                InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

                ContentData.InvolvedCode.Add(InvolvedSourceCode);
                #endregion

                #region Controller
                ContentData.InvolvedCode.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "Controller", TabStripContent = "/Controllers/AdvancedSamples_OrderWithDetailsController.cs" });
                #endregion

                #region Models
                InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
                InvolvedSourceCode.TabStripName = "Models";
                InvolvedSourceCode.TabStripContent = string.Empty;
                InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;
                InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "AdvancedSamples_OrderWithDetailsModel", TabStripContent = "/Models/AdvancedSamples_OrderWithDetailsModel.cs" });
                InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "Order_MetaModel", TabStripContent = "/Models/MetaModels/OrderManagement/Order_MetaModel.cs" });
                InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "OrderDetail_MetaModel", TabStripContent = "/Models/MetaModels/OrderManagement/OrderDetail_MetaModel.cs" });
                InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "OrderTotal_MetaModel", TabStripContent = "/Models/MetaModels/OrderManagement/OrderTotal_MetaModel.cs" });
                ContentData.InvolvedCode.Add(InvolvedSourceCode);
                ContentData.InvolvedCode.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "JSon Model", TabStripContent = "/Models/JSonModels/OrderDetail_JSonModel.cs" });
                #endregion

                #region Javascripts
                InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
                InvolvedSourceCode.TabStripName = "Javascripts";
                InvolvedSourceCode.TabStripContent = string.Empty;
                InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;
                InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Javascript, TabStripName = "View JS", TabStripContent = "/Scripts/InnovacallJS/AdvancedSamples_OrderWithDetails/AdvancedSamples_OrderWithDetails.js" });
                InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Javascript, TabStripName = "Layout JS", TabStripContent = "/Scripts/InnovacallJS/_Layout/_Layout.js" });
                ContentData.InvolvedCode.Add(InvolvedSourceCode);
                #endregion

                #region CSS
                InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
                InvolvedSourceCode.TabStripName = "CSS";
                InvolvedSourceCode.TabStripContent = string.Empty;
                InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;
                InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Css, TabStripName = "View CSS", TabStripContent = "/Content/Views/AdvancedSamples_OrderWithDetails.css" });
                InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Css, TabStripName = "Form Common CSS", TabStripContent = "/Content/_FormCommon.css" });
                InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Css, TabStripName = "Site (Layout) CSS", TabStripContent = "/Content/_Site.css" });
                ContentData.InvolvedCode.Add(InvolvedSourceCode);
                #endregion

                #region Generated client files
                InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
                InvolvedSourceCode.TabStripName = "Generated client files";
                InvolvedSourceCode.TabStripContent = string.Empty;
                InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;

                InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
                InvolvedSubSourceCode.TabStripName = "Javascript";
                InvolvedSubSourceCode.TabStripContent = string.Empty;
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "Controller", TabStripContent = "/Controllers/ScriptsGController.cs" });
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "View", TabStripContent = "/Views/ScriptsG/inoAdvancedSamples_OrderWithDetailsDynamic.cshtml" });
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.GeneratedJavascript, TabStripName = "Generated javascript", TabStripContent = "/ScriptsG/inoAdvancedSamples_OrderWithDetailsDynamic.js" });
                InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

                InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
                InvolvedSubSourceCode.TabStripName = "CSS";
                InvolvedSubSourceCode.TabStripContent = string.Empty;
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "Controller", TabStripContent = "/Controllers/CSSGController.cs" });
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "View", TabStripContent = "/Views/CSSG/site.cshtml" });
                InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.GeneratedCss, TabStripName = "Generated CSS (from _site.css)", TabStripContent = "/CSSG/Site.css" });
                InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

                ContentData.InvolvedCode.Add(InvolvedSourceCode);
                #endregion


                RenderCodeFiles(ContentData.InvolvedCode);

                #endregion
            }
            return View(ContentData);
        }

        /// <summary>
        /// Add detail row in model (no database persistance yet)
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
        public JsonResult AddRow(AdvancedSamples_OrderWithDetailsModel model)
        {
            string eMethod = eMethodBase + "AddRow[POST]";
            object eParameters = new { model = "model" };
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            int newId = -1;
            if (model.CurrentOrder.Details.Count > 0)
            {
                ///New rows have negative id, this query find the smaller and remove 1
                newId = model.CurrentOrder.Details.Where(x => x.Id < 0).OrderByDescending(x => x.Id).First().Id - 1;
            }
            model.CurrentOrder.NewRow.Id = newId;
            model.CurrentOrder.NewRow.RowMode = OrderDetail_MetaModel.enOrderDetailRowMode.Remove;
            model.CurrentOrder.Details.Add(model.CurrentOrder.NewRow);
            string htmlContent = PrepareContent(model);
            //string htmlContent = base.RenderPartialViewToString("_AdvancedSamples_OrderWithDetails_DetailRefresh", model);
            toReturn.Data = new { @success = true, @divToUpdate = "#divOrderDetailContainer", @htmlContent = htmlContent, @scriptToExecute = "$.fn.ReloadLists();" };
            return toReturn;
        }

        private string PrepareContent(AdvancedSamples_OrderWithDetailsModel model)
        {
            string toReturn = string.Empty;
            model.CurrentOrder.NewRow = EmptyNewRow(model.CurrentOrder.Id);
            //There is no persistance for row mode
            model.CurrentOrder.Totals = new OrderTotal_MetaModel();
            int rowId = -1;
            foreach (var d in model.CurrentOrder.Details)
            {
                d.RowMode = OrderDetail_MetaModel.enOrderDetailRowMode.Remove;

                d.Id = rowId;

                model.CurrentOrder.Totals.ExcludingTaxesTotal += d.TotalPrice;
                model.CurrentOrder.Totals.TaxesTotal += d.VatTotal;
                model.CurrentOrder.Totals.IncludedTaxesTotal += d.AllTaxeIncludedTotal;

                rowId--;
            }
            toReturn = this.RenderViewToString("_AdvancedSamples_OrderWithDetails_DetailRefresh", model);
            return toReturn;
        }

        /// <summary>
        /// Remove an existing Row in model, the row is tagged "isRemoved=true"
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
        public JsonResult RemoveRow(int Id, AdvancedSamples_OrderWithDetailsModel model)
        {
            string eMethod = eMethodBase + "RemoveRow[POST]";
            object eParameters = new { model = "model" };
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            model.CurrentOrder.Details.Remove(model.CurrentOrder.Details.Where(x => x.Id == Id).First());
            int i = -1;
            model.CurrentOrder.Details.Where(x => x.Id < 0).ToList().ForEach(x => x.Id = i--);
            string htmlContent = PrepareContent(model);
            toReturn.Data = new { @success = true, @divToUpdate = "#divOrderDetailContainer", @htmlContent = htmlContent, @scriptToExecute = "$.fn.ReloadLists();" };
            return toReturn;
        }

        /// <summary>
        /// Final post, the order is saved in the database
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
        public JsonResult Index(AdvancedSamples_OrderWithDetailsModel model)
        {
            string eMethod = eMethodBase + "Index[POST]";
            object eParameters = new { model = "model" };
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            //if model.Id = -1, new order
            Order orderToAddUpdate;
            using (TransactionScope _ts = new TransactionScope())
            {
                using (DataRepositories _dataContext = new DataRepositories())
                {
                    //Persist to database
                }
                _ts.Complete();
            }
            return toReturn;
        }

        /// <summary>
        /// GetItemDescription
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache -- Authorize, Removed for search engine indexing
        public JsonResult GetDeliveryModeDescriptionDescription(int Id)
        {
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            string htmlResult;
            using (DataRepositories _dataContext = new DataRepositories())
            {
                htmlResult = Server.HtmlEncode(StringEnum.GetStringValue(EnumTools.EnumTypeTo<enDeliveryModes>(Id)));
                toReturn.Data = new { @success = true, @divToUpdate = "#divDeliveryModeDescription", @htmlResult = htmlResult };
            }
            return toReturn;
        }

        /// <summary>
        /// UpdateRow
        /// </summary>
        /// <param name="IdproductId"></param>
        /// <returns></returns>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache -- Authorize, Removed for search engine indexing
        public JsonResult UpdateDetailRowAndTotals(
            int id,
            string orderRef,
            int rowId,
            int productId,
            int qty,
            decimal currentRow_TotalPrice,
            decimal currentRow_VatTotal,
            decimal currentRow_AllTaxeIncludedTotal,
            decimal totals_ExcludingTaxesTotal,
            decimal totals_TaxesTotal,
            decimal totals_IncludedTaxesTotal
        )
        {
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            OrderDetail_JSonModel toReturnData;
            using (DataRepositories _dataContext = new DataRepositories())
            {
                toReturnData = PrepareRow(_dataContext, id, orderRef, rowId, productId, qty, currentRow_TotalPrice, currentRow_VatTotal, currentRow_AllTaxeIncludedTotal, totals_ExcludingTaxesTotal, totals_TaxesTotal, totals_IncludedTaxesTotal);
            }
            toReturn.Data = toReturnData.Data;
            return toReturn;
        }

        /// <summary>
        /// UpdateRow
        /// </summary>
        /// <param name="IdproductId"></param>
        /// <returns></returns>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache -- Authorize, Removed for search engine indexing
        public JsonResult UpdateRow(int productId, int qty)
        {
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            string htmlResult;
            if (productId > 0)
            {
                using (DataRepositories _dataContext = new DataRepositories())
                {
                    Product dbProduct = _dataContext.Product_Rep.Query(x => x.Id == productId).FirstOrDefault();
                    if (dbProduct != null)
                    {
                        double vat = dbProduct.VAT.Value;
                        double totalPrice = double.Parse(dbProduct.UnitPrice.ToString()) * qty;
                        double allTaxeIncludedTotal = totalPrice * (1 + vat / 100);
                        double vatTotal = allTaxeIncludedTotal - totalPrice;
                        toReturn.Data = new
                        {
                            @success = true,
                            @productDescription = dbProduct.Description,
                            @unitPrice = string.Format("{0:0.00}", dbProduct.UnitPrice),
                            @totalPrice = string.Format("{0:0.00}", totalPrice),
                            @appliedVATRate = string.Format("{0:0.00}", vat),
                            @vatTotal = string.Format("{0:0.00}", vatTotal),
                            @allTaxeIncludedTotal = string.Format("{0:0.00}", allTaxeIncludedTotal)
                        };
                    }
                    else
                    {
                        toReturn.Data = new { @success = false, @message = Resources.View_Order_ErrMsg_ProductNotFound };
                    }
                }
            }
            else
            {
                toReturn.Data = new
                {
                    @success = true,
                    @productDescription = string.Empty,
                    @unitPrice = "0.00",
                    @totalPrice = "0.00",
                    @appliedVATRate = "0.00",
                    @vatTotal = "0.00",
                    @allTaxeIncludedTotal = "0.00"
                };
            }
            return toReturn;
        }

        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache -- Authorize, Removed for search engine indexing
        public JsonResult GetAddress(int Id, string textAreaToUpdate)
        {
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            string htmlResult;
            using (DataRepositories _dataContext = new DataRepositories())
            {
                ContactAddress dbAddress = _dataContext.ContactAddress_Rep.Query(x => x.Id == Id).FirstOrDefault();
                htmlResult = Server.HtmlEncode(dbAddress.Address_1) + "<br/>";
                if (!string.IsNullOrEmpty(dbAddress.Address_2))
                {
                    htmlResult += Server.HtmlEncode(dbAddress.Address_2) + "<br/>";
                }
                if (!string.IsNullOrEmpty(dbAddress.Address_3))
                {
                    htmlResult += Server.HtmlEncode(dbAddress.Address_3) + "<br/>";
                }
                htmlResult += Server.HtmlEncode(dbAddress.ZipCode) + "&nbsp;" + Server.HtmlEncode(dbAddress.Town) + "<br/>";
                htmlResult += Server.HtmlEncode(dbAddress.Country);

                toReturn.Data = new { @success = true, @divToUpdate = textAreaToUpdate, @htmlResult = htmlResult };
            }
            return toReturn;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_dataContext"></param>
        /// <param name="id">db Id of Current Order</param>
        /// <param name="orderRef">Text order reférence</param>
        /// <param name="rowId"></param>
        /// <param name="productId"></param>
        /// <param name="qty"></param>
        /// <returns></returns>
        private OrderDetail_JSonModel PrepareRow(
            DataRepositories _dataContext,
            int id,
            string orderRef,
            int rowId,
            int productId,
            int qty,
            decimal currentRow_TotalPrice,
            decimal currentRow_VatTotal,
            decimal currentRow_AllTaxeIncludedTotal,
            decimal totals_ExcludingTaxesTotal,
            decimal totals_TaxesTotal,
            decimal totals_IncludedTaxesTotal
        )
        {
            OrderDetail_JSonModel toReturn = new OrderDetail_JSonModel();
            Product dbProduct = _dataContext.Product_Rep.Query(x => x.Id == productId).FirstOrDefault();
            if (dbProduct != null)
            {
                double vat = dbProduct.VAT.Value;
                double totalPrice = double.Parse(dbProduct.UnitPrice.ToString()) * qty;
                double allTaxeIncludedTotal = totalPrice * (1 + vat / 100);
                double vatTotal = allTaxeIncludedTotal - totalPrice;
                toReturn.appliedVATRate = dbProduct.VAT.Value;
                toReturn.unitPrice = double.Parse(dbProduct.UnitPrice.ToString());
                toReturn.message = string.Empty;
                toReturn.productDescription = dbProduct.Description;
                toReturn.success = true;
                toReturn.totalPrice = totalPrice;
                toReturn.unitPrice = double.Parse(dbProduct.UnitPrice.ToString());
                toReturn.vatTotal = vatTotal;
                toReturn.allTaxeIncludedTotal = allTaxeIncludedTotal;
                if (id == -99)
                {
                    toReturn.updateTotals = false;
                    toReturn.totals_ExcludingTaxesTotal = 0;
                    toReturn.totals_TaxesTotal = 0;
                    toReturn.totals_IncludedTaxesTotal = 0;
                }
                else
                {
                    toReturn.updateTotals = true;
                    toReturn.totals_ExcludingTaxesTotal = (double)totals_ExcludingTaxesTotal - (double)currentRow_TotalPrice + toReturn.totalPrice;
                    toReturn.totals_TaxesTotal = (double)totals_TaxesTotal - (double)currentRow_VatTotal + toReturn.vatTotal;
                    toReturn.totals_IncludedTaxesTotal = (double)totals_IncludedTaxesTotal - (double)currentRow_AllTaxeIncludedTotal + toReturn.allTaxeIncludedTotal;
                }
            }
            else
            {
                toReturn.appliedVATRate = 0;
                toReturn.unitPrice = 0;
                toReturn.message = string.Empty;
                toReturn.productDescription = string.Empty;
                toReturn.success = true;
                toReturn.totalPrice = 0;
                toReturn.unitPrice = 0;
                toReturn.vatTotal = 0;
                toReturn.allTaxeIncludedTotal = 0;
                toReturn.updateTotals = false;
                toReturn.totals_ExcludingTaxesTotal = 0;
                toReturn.totals_TaxesTotal = 0;
                toReturn.totals_IncludedTaxesTotal = 0;
            }

            return toReturn;
        }

        /// <summary>
        /// This private method feed MetaModel items
        /// </summary>
        /// <param name="_dataContext"></param>
        /// <returns></returns>
        private void PrepareEmptyOrder(DataRepositories _dataContext)
        {
            string eMethod = eMethodBase + ".PrepareEmptyOrder";
            object eParameters = new { @_dataContext = "[DataContext]" };

            IEnumerable<VAT> dbVATs = _dataContext.VAT_Rep.GetAll().AsEnumerable();

            ContentData.VATs = new List<SelectListItem>(
                dbVATs.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.Description, Selected = false }).AsEnumerable()
            );
            ContentData.VATs.Insert(0, new SelectListItem() { Value = "-1", Text = " ", Selected = true });

            IEnumerable<Product> dbProducts = _dataContext.Product_Rep.GetAll().OrderBy(x => x.Name).AsEnumerable();
            ContentData.Products = new List<SelectListItem>(
                dbProducts.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.Name, Selected = false }).AsEnumerable()
            );
            ContentData.Products.Insert(0, new SelectListItem() { Value = "-1", Text = " ", Selected = true });

            ContentData.CurrentOrder = new Models.MetaModels.Order_MetaModel();
            ContentData.CurrentOrder.OrderRef = "NEW";
            ContentData.CurrentOrder.Id = -1;
            ContentData.CurrentOrder.CurrentContact = base.CurrentContactGet(_dataContext);
            ContentData.CurrentOrder.FK_Contact = ContentData.CurrentOrder.CurrentContact.Id;

            IEnumerable<DeliveryMode> dbDeliveryModes = _dataContext.DeliveryMode_Rep.GetAll().OrderBy(x => x.SortIndex).AsEnumerable();
            ContentData.CurrentOrder.DeliveryModes = new List<SelectListItem>(
                dbDeliveryModes.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.Name, Selected = false }).AsEnumerable()
            );
            ContentData.CurrentOrder.DeliveryModes.Insert(0, new SelectListItem() { Value = "-1", Text = " ", Selected = true });

            ContentData.CurrentOrder.OrderDate = DateTime.Now;
            ContentData.CurrentOrder.FK_DeliveryMode = -1;

            ContentData.CurrentOrder.DeliveryAddresses = _dataContext.Contact__AdressType__ContactAddress_Rep.Query(x => x.FK_Contact == ContentData.CurrentOrder.FK_Contact && x.AddressType.isDelivery == true).Select(x => new SelectListItem() { Value = x.ContactAddress.Id.ToString(), Text = x.ContactAddress.Address_1 + " ... ", Selected = false }).ToList();
            ContentData.CurrentOrder.DeliveryAddresses.Insert(0, new SelectListItem() { Value = "-1", Text = string.Empty, Selected = true });

            ContentData.CurrentOrder.InvoicingAddresses = _dataContext.Contact__AdressType__ContactAddress_Rep.Query(x => x.FK_Contact == ContentData.CurrentOrder.FK_Contact && x.AddressType.isBilling == true).Select(x => new SelectListItem() { Value = x.ContactAddress.Id.ToString(), Text = x.ContactAddress.Address_1 + " ... ", Selected = false }).ToList();
            ContentData.CurrentOrder.InvoicingAddresses.Insert(0, new SelectListItem() { Value = "-1", Text = string.Empty, Selected = true });

            ContentData.CurrentOrder.NewRow = EmptyNewRow(ContentData.CurrentOrder.Id);

            ContentData.CurrentOrder.Details = new List<Models.MetaModels.OrderManagement.OrderDetail_MetaModel>();
        }

        private OrderDetail_MetaModel EmptyNewRow(int orderId)
        {
            OrderDetail_MetaModel toReturn = new OrderDetail_MetaModel();
            toReturn.RowMode = OrderDetail_MetaModel.enOrderDetailRowMode.Add;
            toReturn.Id = -99;
            toReturn.AllTaxeIncludedTotal = 0;
            toReturn.AppliedVATRate = 0;
            toReturn.FK_Order = orderId;
            toReturn.FK_Product = -1;
            toReturn.Quantity = 0;
            toReturn.TotalPrice = 0;
            toReturn.UnitPrice = 0;
            toReturn.VatTotal = 0;
            return toReturn;
        }
    }
}


///// <summary>
///// Update a row, it can be the NewRow id=0, a added row (id lesser than 0) or an existing row id greater than 0
///// </summary>
///// <param name="rowId"></param>
///// <param name="model"></param>
///// <returns></returns>
//[HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
//public JsonResult UpdateRow(int rowId, AdvancedSamples_OrderWithDetailsModel model)
//{
//    string eMethod = eMethodBase + "UpdateRow[POST]";
//    object eParameters = new { model = "model" };
//    JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
//    using (DataRepositories _dataContext = new DataRepositories())
//    {
//        if (rowId == -99)
//        {
//            model.CurrentOrder.NewRow = PrepareRow(_dataContext, model.CurrentOrder.Id, model.CurrentOrder.NewRow);
//        }
//        else
//        {
//            List<OrderDetail_MetaModel> newDetails = new List<OrderDetail_MetaModel>();
//            OrderDetail_MetaModel detailToAdd;
//            foreach (OrderDetail_MetaModel currentDetail in model.CurrentOrder.Details)
//            {
//                if (currentDetail.Id != rowId)
//                {
//                    detailToAdd = PrepareRow(_dataContext, model.CurrentOrder.Id, currentDetail);
//                }
//                else
//                {
//                    detailToAdd = currentDetail;
//                }
//                newDetails.Add(detailToAdd);
//            }
//            model.CurrentOrder.NewRow = EmptyNewRow(model.CurrentOrder.Id);
//            model.CurrentOrder.Details = newDetails;
//        }
//    }
//    string htmlContent = base.RenderPartialViewToString("_AdvancedSamples_OrderWithDetails_DetailRefresh", model);
//    toReturn.Data = new { @success = true, @htmlContent = htmlContent, @scriptToExecute = "$.fn.RebindButtons();" };
//    return toReturn;
//}

//private OrderDetail_MetaModel PrepareRow(DataRepositories _dataContext, int orderId, OrderDetail_MetaModel orderDetail)
//{
//    OrderDetail_MetaModel toReturn;
//    Product dbProduct = _dataContext.Product_Rep.Query(x => x.Id == orderDetail.FK_Product).FirstOrDefault();
//    if (dbProduct != null)
//    {
//        double vat = dbProduct.VAT.Value;
//        double totalPrice = double.Parse(dbProduct.UnitPrice.ToString()) * orderDetail.Quantity;
//        double allTaxeIncludedTotal = totalPrice * (1 + vat / 100);
//        double vatTotal = allTaxeIncludedTotal - totalPrice;
//        toReturn = new OrderDetail_MetaModel()
//        {
//            Id = orderDetail.Id,
//            FK_Order = orderId,
//            FK_Product = orderDetail.FK_Product,
//            Quantity = orderDetail.Quantity,
//            AppliedVATRate = decimal.Parse(vat.ToString()),
//            TotalPrice = decimal.Parse(totalPrice.ToString()),
//            VatTotal = decimal.Parse(vatTotal.ToString()),
//            AllTaxeIncludedTotal = decimal.Parse(allTaxeIncludedTotal.ToString())
//        };
//    }
//    else
//    {
//        toReturn = new OrderDetail_MetaModel()
//        {
//            Id = orderDetail.Id,
//            FK_Order = orderId,
//            FK_Product = orderDetail.FK_Product,
//            Quantity = orderDetail.Quantity,
//            AppliedVATRate = 0,
//            TotalPrice = 0,
//            VatTotal = 0,
//            AllTaxeIncludedTotal = 0
//        };
//    }
//    return toReturn;
//}